package com.likersai.opon.system.interceptor;

import com.likersai.opon.pojo.bo.EntityBO;
import com.likersai.opon.system.exception.OponException;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.Properties;

import static com.likersai.opon.constant.ExceptionMsg.SQL_NO_WHERE;

/**
 * Mybatis拦截器
 *
 * @author sun.ye
 * @since 2022-06-10 11:31
 */
@Slf4j
@Component
@Intercepts({
        @Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class}),
        @Signature(method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
})
public class MyBaitsInterceptor implements Interceptor{
    
    @Override
    public Object intercept (Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        Object target = invocation.getTarget();
        Object method = invocation.getMethod();
    
        MappedStatement statement = (MappedStatement) args[0];
        String sql = statement.getBoundSql(args[1]).getSql();
    
        setBaseEntityInfo(args);
        checkSql(sql);
        
        return invocation.proceed();
    }
    
    @Override
    public Object plugin (Object target) {
        if (target instanceof Executor){
            return Plugin.wrap(target,this);
        }
        return target;
    }
    
    @Override
    public void setProperties (Properties properties) {
    
    }
    
    private void checkSql(String sql) {
       
        //处理sql
        sql = sql.toUpperCase();
        if(sql.startsWith("INSERT INTO")){
            return;
        }
        if(sql.startsWith("SELECT")){
            return;
        }
        if(!sql.contains("WHERE")){
            throw new OponException(SQL_NO_WHERE);
        }
    }
    
    public void setBaseEntityInfo(Object[] args){
        if (args == null || args.length == 0){
            return;
        }
        
        for (Object arg : args) {
            if (arg instanceof EntityBO){
                EntityBO entityBO = (EntityBO) arg;
                if (entityBO.hasNoTime()){
                    entityBO.initDate();
                }
            }
        }
    }
}